package cn.xinfei.xdecision.engine.runner.utils;

import cn.xinfei.xdecision.common.vo.FieldInfoVo;
import cn.xinfei.xdecision.engine.runner.context.PipelineContext;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;

import java.util.*;

@Slf4j
public class ScriptHelper {


    /**
     * 根据输入变量参数返回衍生变量的结果
     * 输入：参数列表(原生变量英文字段名和值、待计算的衍生字段只有英文字段名)
     * 输出：待计算衍生字段的计算结果值
     */
//    public void getFieldResult(Map<String, Object> paramMap) {
//        //参数传递中间临时Map
//        Map<String, Object> paramMap2 = new HashMap<String, Object>();
//        for (Map.Entry<String, Object> entry : paramMap.entrySet()) {
//            if (null != entry.getValue()) {
//                paramMap2.put(entry.getKey(), entry.getValue());
//            } else {
//                paramMap2.put(entry.getKey(), "");
//            }
//        }
//
//
//
//        List<VariableCallLog> varCallLogs = new ArrayList<>();
//        for (Map.Entry<String, Object> entry : paramMap.entrySet()) {
//            String varCode = entry.getKey();
//            String fieldValue = "";
//            if (null != entry.getValue()) {
//                fieldValue = String.valueOf(entry.getValue());
//            }
//
//            if (null == fieldValue || fieldValue.equals("")) {
//
//                paramMap2.put("varEn", fieldEn);
//                Field field = fieldService.findByFieldEnbyorganId(organId, fieldEn);
//
//                if (field != null) {
//                    if (field.getIsDerivative() == 1) {
//                        long start = System.currentTimeMillis();
//                        String result = "";
//                        paramMap2.put("fieldCn", field.getFieldCn());
//                        result = getExpAll(field.getFieldCn(), "", paramMap);
//                        //单独返回数值结果会带上()，做处理去掉
//                        result = result.replace("(", "");
//                        result = result.replace(")", "");
//                        long end = System.currentTimeMillis();
//                        fieldCallLogs.add(new FieldCallLog(field.getId(),FieldTypeConsts.DERIVE,FieldTypeConsts.DERIVE,
//                                FieldTypeConsts.DERIVE_SOURCE_ID, JSON.toJSONString(paramMap),result,(end-start),field.getOrganId()));
//                        paramMap.put(fieldEn, result);
//                    }
//                }
//            }
//        }
//        if (!fieldCallLogs.isEmpty()){
//            fieldCallLogService.saveBatch(fieldCallLogs);
//        }
//    }
//
//    /**
//     * 递归生成衍生变量嵌套的逻辑表达式或公式计算的结果
//     */
//    private String getExpAll(String fieldCn, String exp, Map<String, Object> param) {
//
//        String result = "";
//        Map<String, Object> param2 = new HashMap<String, Object>();
//        for (Map.Entry<String, Object> entry : param.entrySet()) {
//            if (null != entry.getValue())
//                param2.put(entry.getKey(), entry.getValue());
//            else
//                param2.put(entry.getKey(), "");
//        }
//
//        SessionData sessionData = RunnerSessionManager.getSession();
//        Long organId = sessionData.getOrganId();
//
//        Map<String, Object> paramMap = new HashMap<String, Object>();
//
//        paramMap.put("organId", organId);
//        paramMap.put("engineId", param.get("engineId"));
//        paramMap.put("fieldCn", fieldCn);
//
//        //放大从组织通用字段拷贝生成的引擎字段里字段的获取范围，优先取引擎，没有再取组织里的（因为中文名在组织通用字段和引擎字段里有重复）
//        String arrFormula = "";
//        Field engField = fieldService.findByFieldCnbyorganId(organId, fieldCn);
//        String engFormula = engField.getFormula();
//        if (!engFormula.equals("") && engFormula != null) {
//            arrFormula = engFormula;
//        }
//
//        if (arrFormula.equals("") || arrFormula == null) { //衍生字段只有条件区域
//
//            List<FieldCond> fieldCondList = new ArrayList<FieldCond>();
//            List<FieldCond> engfieldCondList = fieldService.findByFieldCnbyorganId(organId, fieldCn).getFieldCondList();
//            if (engfieldCondList.size() > 0) {
//                fieldCondList = engfieldCondList;
//            }
//
//            if (fieldCondList.size() > 0) {//需要进行条件区域逻辑运算
//                for (FieldCond fieldCond : fieldCondList) {//这里的fieldCond是字段设置的逻辑运算符
//                    String condValue = fieldCond.getConditionValue();
//                    List<Object> condList = new ArrayList<>();
//                    condList = JSONObject.parseArray(fieldCond.getContent());
//                    exp = "";
//                    for (int j = 0; j < condList.size(); j++) {
//                        JSONObject cond = ((JSONArray) condList).getJSONObject(j);
//                        //[{\"fieldId\":\"31\",\"operator\":\">\",\"fieldValue\":\"1000\",\"logical\":\"&&\"},{\"fieldId\":\"31\",\"operator\":\">=\",\"fieldValue\":\"7000\"}]
//                        paramMap.put("id", cond.getString("fieldId"));
//
//                        Field condfield = fieldService.queryById(Long.valueOf(cond.getString("fieldId")));
//                        if (condfield == null) {
//                            condfield = fieldService.findByFieldCnbyorganId(organId, fieldCn);
//                        }
//
//                        String condFieldEn = condfield.getFieldEn();//yqshouru 月收入
//                        String condFieldCn = condfield.getFieldCn();
//                        Integer condValueType = condfield.getValueType(); //1数值型
//                        String condFieldValue = cond.getString("fieldValue"); //1000
//                        String operator = cond.getString("operator"); //>大于号
//                        String fieldValue = param2.get(condFieldEn).toString(); //取输入变量的值
//
//                        String logical = "";
//
//                        if (condfield.getIsDerivative() == 0) {
//                            if (cond.containsKey("logical"))
//                                logical = " " + cond.getString("logical") + " ";
//                            if (operator.equals("in")) {
//                                //exp += "(indexOf(#{"+fieldValue+"},'"+condFieldValue+"')>0"+logical;
//                                exp += "(indexOf('" + condFieldValue + "','" + fieldValue + "',0) >= 0)" + logical;
//                            } else if (operator.equals("not in")) {
//                                //exp += "(indexOf(#{"+fieldValue+"},'"+condFieldValue+"')=0"+logical;
//                                exp += "(indexOf('" + condFieldValue + "','" + fieldValue + "',0) = -1)" + logical;
//                            } else if (operator.equals("like")) { //交换位置 (indexOf('abc','c',0) >= 0)
//                                exp += "(indexOf('" + fieldValue + "','" + condFieldValue + "',0) >= 0)" + logical;
//                            } else if (operator.equals("not like")) { //(indexOf('abc','x',0) = -1)
//                                exp += "(indexOf('" + fieldValue + "','" + condFieldValue + "',0) = -1)" + logical;
//                            } else {
//                                if (condValueType == 1 || condValueType == 4) {
//                                    exp += " (" + fieldValue + "" + operator + "" + condFieldValue + ") " + logical;
//                                } else
//                                    exp += " ('" + fieldValue + "'" + operator + "'" + condFieldValue + "') " + logical;
//                            }
//                        } else {//衍生字段
//                            if (cond.containsKey("logical"))
//                                logical = " " + cond.getString("logical") + " ";
//                            if (operator.equals("in")) {
//                                //exp += "(indexOf(#{"+getExpAll(condFieldCn,"",param2)+"},'"+condFieldValue+"')>0"+logical;
//                                //(indexOf('abc','c',0) >= 0) && (indexOf('abc','x',0) = -1)
//                                exp += "(indexOf('" + condFieldValue + "','" + getExpAll(condFieldCn, "", param2) + "',0) >= 0)" + logical;
//                            } else if (operator.equals("not in")) {
//                                exp += "(indexOf('" + condFieldValue + "','" + getExpAll(condFieldCn, "", param2) + "',0) = -1)" + logical;
//                            } else if (operator.equals("like")) { //交换位置 (indexOf('abc','c',0) >= 0)
//                                exp += "(indexOf('" + getExpAll(condFieldCn, "", param2) + "','" + condFieldValue + "',0) >= 0)" + logical;
//                            } else if (operator.equals("not like")) { //(indexOf('abc','x',0) = -1)
//                                exp += "(indexOf('" + getExpAll(condFieldCn, "", param2) + "','" + condFieldValue + "',0) = -1)" + logical;
//                            } else {
//                                if (condValueType == 1 || condValueType == 4) {
//                                    exp += " (" + getExpAll(condFieldCn, "", param2) + "" + operator + "" + condFieldValue + ") " + logical;
//                                } else
//                                    exp += " ('" + getExpAll(condFieldCn, "", param2) + "'" + operator + "'" + condFieldValue + "') " + logical;
//                            }
//                        }
//                    }
//                    Evaluator evaluator = new Evaluator();
//                    String b = "";
//                    try {
//                        System.out.println("========字段区域设置的的表达式输出：" + exp);
//                        b = evaluator.evaluate(exp);
//                    } catch (EvaluationException e) {
//                        e.printStackTrace();
//                        logger.error("请求异常", e);
//                    }
//                    if (b.equals("1.0")) {
//                        result = condValue;
//                        break; //遇到一个满足条件的则跳出循环
//                    }
//                }
//            }
//        } else { //衍生字段只有公式
//            List<Object> formulaList = new ArrayList<>();
//            formulaList = JSONObject.parseArray(arrFormula);
//            for (int i = 0; i < formulaList.size(); i++) {
//                JSONObject formulaJson = ((JSONArray) formulaList).getJSONObject(i);
//
//                String formula = (String) formulaJson.get("formula");
//                formula = formula.replace("&gt;", ">"); //3&gt;=6 && 3&lt; 12
//                formula = formula.replace("&lt;", "<");
//                Pattern pattern = Pattern.compile("@[a-zA-Z0-9_\u4e00-\u9fa5()（）-]+@");
//                Matcher matcher = pattern.matcher(formula);
//                String subexp = formula;
//                int j = 0;
//                exp = "";
//                // 存放groovy脚本入参
//                Map<String, Object> data = new HashMap<>();
//                //System.out.println("待替换的字段串："+formula);
//                while (matcher.find()) {
//                    String fieldCN = matcher.group(0).replace("@", "");
//                    Map<String, Object> fieldMap = new HashMap<String, Object>();
//                    paramMap.put("organId", organId);
//                    fieldMap.put("engineId", paramMap.get("engineId"));
//                    fieldMap.put("fieldCn", fieldCN);
//                    fieldMap.put("organId", organId);
//                    Field subField = fieldService.findByFieldCnbyorganId(organId, fieldCN);
//
//                    //构造字段条件区间计算输入参数
//                    Map<String, Object> paramCond = new HashMap<String, Object>();
//                    paramCond.put("fieldValue", param2.get(subField.getFieldEn()));
//                    paramCond.put("fieldEn", subField.getFieldEn());
//                    paramCond.put("fieldValueType", subField.getValueType());
//
//                    //字段条件转换
//                    JSONArray fieldCond = new JSONArray();
//                    if (formulaJson.get("farr") != null && !"".equals(formulaJson.get("farr"))) {
//                        JSONArray jsonArr = (JSONArray) formulaJson.get("farr");
//                        for (Iterator iterator = jsonArr.iterator(); iterator.hasNext(); ) {
//                            JSONObject job = (JSONObject) iterator.next();
//                            if (job.get("fieldCN").equals(fieldCN) && !job.get("fieldCond").equals("")) {
//                                fieldCond = (JSONArray) job.get("fieldCond");
//                                break;
//                            }
//                        }
//                    }
//
//                    paramCond.put("fieldCond", fieldCond);
//                    String v = "";
//                    if (fieldCond.size() > 0) {
//                        v = calcFieldCond(paramCond);
//                    } else {
//                        v = "" + param2.get(subField.getFieldEn());
//                    }
//                    data.put(subField.getFieldEn(), param2.get(subField.getFieldEn()));
//
//                    if (subField.getIsDerivative() == 0) {
////						if(subexp.indexOf("substring")>=0||subexp.indexOf("equals")>=0){ //substring(@字段A@,3,6)
////							exp += subexp.substring(j, matcher.end()).replace("@"+fieldCN+"@", "'"+v+"'");
////						}else{
////							exp += subexp.substring(j, matcher.end()).replace("@"+fieldCN+"@", v);
////						}
//
//                        if (subexp.contains("def main")) {
//                            // groovy脚本替换为动态参数
//                            v = "_['" + subField.getFieldEn() + "']";
//                            exp += subexp.substring(j, matcher.end()).replace("@" + fieldCN + "@", v);
//                        } else {
//                            if (subField.getValueType() == 1 || subField.getValueType() == 4) {
//                                exp += subexp.substring(j, matcher.end()).replace("@" + fieldCN + "@", v);
//                            } else {
//                                exp += subexp.substring(j, matcher.end()).replace("@" + fieldCN + "@", "'" + v + "'");
//                            }
//                        }
//
//                    } else {
//
//                        v = getExpAll(fieldCN, exp, param2);
//                        // 存衍生字段
//                        if (subField.getValueType() == 1 || subField.getValueType() == 4) {
//                            data.put(subField.getFieldEn(), Integer.valueOf(v));
//                        } else {
//                            data.put(subField.getFieldEn(), v);
//                        }
//
//                        if (subexp.contains("def main")) {
//                            // groovy脚本替换为动态参数
//                            v = "_['" + subField.getFieldEn() + "']";
//                        }
//                        exp += subexp.substring(j, matcher.end()).replace("@" + fieldCN + "@", v);
//                    }
//                    j = matcher.end();
//                }
//                exp += formula.substring(j, formula.length());
//                Evaluator evaluator = new Evaluator();
//                String b = "";
//                try {
////                    System.out.println("========字段公式编辑设置的表达式输出：" + exp);
//
//                    if (exp.contains("def main")) {
//                        // 执行groovy脚本
//                        b = groovy.execute(exp, data);
////                        b = String.valueOf(groovy.execute(exp, data));
//                    } else {
//                        b = evaluator.evaluate(exp);
//                    }
//
//                } catch (EvaluationException e) {
//                    e.printStackTrace();
//                    logger.error("请求异常", e);
//                }
//
//                //
//                if (engField.getValueType().intValue() == 1 || engField.getValueType().intValue() == 2) { //数值型或者字符型字段的衍生表达式b的结果返回值0.0代表计算结果
//                    if (!b.equals("")) {
//                        result = b;
//                        if (StringUtil.isValidStr(result) && result.startsWith("'") && result.endsWith("'")) {
//                            result = result.substring(1, result.length() - 1);
//                        }
//                    }
//                } else if (engField.getValueType().intValue() == 3) { //枚举型字段的衍生表达式b的结果返回值0.0代表false即逻辑表达式无效
//                    if (!b.equals("1.0") && !b.equals("0.0") && !b.equals("")) {
//                        result = b;
//                        if (StringUtil.isValidStr(result) && result.startsWith("'") && result.endsWith("'")) {
//                            result = result.substring(1, result.length() - 1);
//                        }
//                    }
//                    if (b.equals("1.0")) {
//                        result = (String) formulaJson.get("fvalue");
//                        //result = result.substring(result.indexOf(":")+1,result.length());// a:2 取2返回
//                        if (isNumeric(result)) {
//                            result = "(" + result + ")";
//                        } else {
//                            result = "'" + result + "'";
//                        }
//                        break; //遇到一个满足条件的则跳出循环
//                    }
//                }
//
//            }
//        }
//
//        return result;
//
//    }




    //根据入参map,通过公式和groovy计算出返回结果
    public final static Map<String, FieldInfoVo> getObjFromScript(PipelineContext input, String fieldValue) {
        JSONObject formulaJson = JSON.parseObject(fieldValue);
        Object farr = formulaJson.get("farr");
        List<String> fieldCodes = new ArrayList<>();
        //变量名为key，变量code为value
        Map<String, FieldInfoVo> variableMap = new HashMap<>();
        if (farr != null && !"".equals(farr)) {
            List<FieldInfoVo> variableList = JSONArray.parseArray(JSON.toJSONString(farr), FieldInfoVo.class);
            for (FieldInfoVo var : variableList) {
                String varName = var.getFieldName();
                String varCode = var.getFieldCode();
                if (varName != null && varCode != null && !"".equals(varName) && !"".equals(varCode)) {
                    variableMap.put(varName, var);
                }
            }
        }
//        if (fieldCodes.size() > 0) {
//            getFieldToInputByIds(fieldCodes, input);
//        }
        return variableMap;
    }




}
